home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
UNIXLIB37B
/
!UnixLib37
/
src
/
unix
/
c
/
wait4
< prev
next >
Wrap
Text File
|
1996-11-09
|
4KB
|
153 lines
/****************************************************************************
*
* $Source: /unixb/home/unixlib/source/unixlib37/src/unix/c/RCS/wait4,v $
* $Date: 1996/10/30 22:04:51 $
* $Revision: 1.2 $
* $State: Rel $
* $Author: unixlib $
*
* $Log: wait4,v $
* Revision 1.2 1996/10/30 22:04:51 unixlib
* Massive changes made by Nick Burret and Peter Burwood.
*
* Revision 1.1 1996/05/06 09:03:14 unixlib
* Initial revision
*
***************************************************************************/
static const char rcs_id[] = "$Id: wait4,v 1.2 1996/10/30 22:04:51 unixlib Rel $";
#include <unixlib/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/unix.h>
#include <errno.h>
#include <stdlib.h>
/* If usage is not null, wait4 returns usage figures for the child
process in *usage (but only if the child has terminated and not
if it has stopped). */
/* wait, wait3 and wait4 are all derivatives of the function, waitpid.
waitpid has been implemented through wait4 for practical reasons.
The waitpid function is used to request status information from
a child process whose process ID is pid. Normally, the calling
process is suspended until the child process makes status information
available by terminating.
Error conditions:
EINTR: The function was interrupted by delivery of a signal to the
calling process.
ECHILD: There are no child processes to wait for, or the specified pid
is not a child of the calling process.
EINVAL: An invalid value was provided for the options argument.
Symbolic constants (through pid):
WAIT_ANY: Value is -1 and specifies that waitpid should return status
information about any child process.
WAIT_MYPGRP: Value is 0 and specifies that waitpid should return
status information about any child process in the same process group
as the calling process.
Symbolic constants (passed through options):
WNOHANG: waitpid should return immediately instead of waiting, if
there is no child process ready to be noticed.
WUNTRACED: waitpid should report the status of any child processes
that have been stopped as well as those that have terminated. */
/* Make conversion of the process exit status easy done. */
static int
wait_convert_status (struct __process *status)
{
if (status->signal_exit)
return __W_EXITCODE (status->return_code, status->signal);
if (status->core_dump)
return __WCOREFLAG;
if (status->stopped)
return __W_STOPCODE (status->signal);
return __W_EXITCODE (status->return_code, 0);
}
/* Make the process of comparing process IDs fairly easy. */
static int
wait_type (__pid_t pid, int p)
{
/* Match any process. */
if (pid == WAIT_ANY)
return 1;
/* Match any process in the current process's group. */
if (pid == WAIT_MYPGRP)
if (__u->child[p].gid == __u->gid)
return 1;
/* Match any process whose process group is the abs(pid). */
if (pid < -1)
if (__u->child[p].gid == abs (pid))
return 1;
/* Match a specific process id. */
if (__u->child[p].pid == pid)
return 1;
/* No match found. */
return 0;
}
__pid_t
wait4 (__pid_t pid, int *status, int options, struct rusage *usage)
{
static int process = 0;
int start_value;
if (options < 0 || options > (WNOHANG + WUNTRACED))
{
errno = EINVAL;
return (__pid_t)-1;
}
start_value = process;
while (1)
{
if (wait_type (pid, process))
if (!__u->child[process].status.stopped
|| ((options & WUNTRACED) && __u->child[process].status.stopped))
{
/* If the untraced bit is set, we will match against
stopped children; otherwise we won't. */
/* Copy the resource usage details (if usage is not null). */
if (usage && __u->child[process].pid == pid)
*usage = __u->child[process].usage;
if (status)
{
*status = wait_convert_status (&__u->child[process].status);
#ifdef DEBUG
printf ("wait4: process = %d, status = %x\n", process, *status);
#endif
}
return __u->child[process].pid;
}
if (++process == CHILD_MAX)
process = 0;
/* If the no hang bit is set and we have found no dead
children, return 0. */
if ((options & WNOHANG) && process == start_value)
{
errno = ECHILD;
return (__pid_t)0;
}
};
return (__pid_t)-1;
}